package com.edu.spring.aop.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AroundAspect {
    @Pointcut("execution(* com.edu.spring.aop.impl.*.*(..))")
    public void pointcut() {
    }

    /**
     * 环绕通知固定写法
     */
    @Around("pointcut()")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object[] args = proceedingJoinPoint.getArgs();// 获取目标方法的参数
        // 前置
        System.out.println("环绕 - 前置通知");

        Object proceed = null;// 继续执行目标方法; 反射：method.invoke()
        try {
            proceed = proceedingJoinPoint.proceed(args);
        } catch (Throwable e) {
            System.out.println("环绕 - 异常通知");
            // 异常通知 抛出异常，异常继续向上抛出，防止导致事务失效。
            throw e;
        } finally {
            System.out.println("环绕 - 后置通知");
        }

        System.out.println("环绕 - 返回通知");
        // 修改返回值
        return proceed;
    }
}
